package com.ls.uav_backend.service.impl;

import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.ls.uav_backend.exception.ErrorCode;
import com.ls.uav_backend.exception.ThrowUtils;
import com.ls.uav_backend.mapper.ChatHistoryMapper;
import com.ls.uav_backend.model.entity.ChatHistory;
import com.ls.uav_backend.model.enums.ChatTypeEnum;
import com.ls.uav_backend.service.ChatHistoryService;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 聊天历史记录 服务层实现。
 *
 * @author <a href="https://gitee.com/Linkating">LinSkating</a>
 */
@Service
public class ChatHistoryServiceImpl extends ServiceImpl<ChatHistoryMapper, ChatHistory> implements ChatHistoryService {

    @Resource
    private RedisTemplate<String, List<Message>> redisTemplate;

    @Override
    public List<Message> loadChatHistory(Integer chatId, int maxCount) {
        String cacheKey = String.valueOf(chatId);
        List<Message> cacheList = redisTemplate.opsForValue().get(cacheKey);
        if (cacheList != null && !cacheList.isEmpty()) {
            return cacheList;
        }
        ThrowUtils.throwIf(chatId == null, ErrorCode.PARAMS_ERROR);
        List<ChatHistory> list = this.queryChain()
                .select(ChatHistory::getMessage, ChatHistory::getType)
                .eq(ChatHistory::getChatId, chatId)
                .orderBy(ChatHistory::getChatTime, false)
                .list();
        if (list.isEmpty()) {
            return new ArrayList<>();
        }
        list = list.reversed();
        List<Message> messages = new ArrayList<>();
        int count = 0;
        for (ChatHistory chatHistory : list) {
            if (ChatTypeEnum.USER.equals(ChatTypeEnum.getEnumByValue(chatHistory.getType()))) {
                messages.add(createMessage(Role.USER, chatHistory.getMessage()));
            } else if (ChatTypeEnum.ASSISTANT.equals(ChatTypeEnum.getEnumByValue(chatHistory.getType()))) {
                messages.add(createMessage(Role.ASSISTANT, chatHistory.getMessage()));
            }
            count++;
            if (count >= maxCount) {
                break;
            }
        }
        redisTemplate.opsForValue().set(cacheKey, messages, Duration.ofMinutes(15));
        return messages;
    }

    @Override
    public Map<Integer, List<ChatHistory>> getChatHistoryList() {
        List<ChatHistory> list = this.list(new QueryWrapper());
        return list.stream()
                .collect(Collectors.groupingBy(
                        ChatHistory::getChatId,
                        LinkedHashMap::new,  // 保证键的插入顺序
                        Collectors.toList()  // 保证值列表的元素顺序
                ));
    }

    private static Message createMessage(Role role, String content) {
        return Message.builder().role(role.getValue()).content(content).build();
    }
}
